package AnaliseSemantica;

import java.util.ArrayList;

import ArvoreSintatica.*;
import Visitor.Visitor;

public class SymbolTableVisitor implements Visitor {

	private TabelaSimbolo tabela;

	public TabelaSimbolo buildSymbolTable(Program program) {
		tabela = new TabelaSimbolo();
		visit(program);
		return tabela;
	}

	public void visit(Program n) {
		n.m.accept(this);
		for (int i = 0; i < n.cl.size(); i++) {
			n.cl.elementAt(i).accept(this);
		}

	}

	public void visit(MainClass n) {
		Simbolo classe = Simbolo.symbol(n.i1.s);
		tabela.addClass(classe);
		tabela.beginScope(classe);
		tabela.endScope();
	}

	public void visit(ClassDeclSimple n) {
		Simbolo classe = Simbolo.symbol(n.i.s);
		tabela.addClass(classe);
		tabela.beginScope(classe);
		for (int i = 0; i < n.vl.size(); i++) {
			n.vl.elementAt(i).accept(this);
		}
		for (int j = 0; j < n.ml.size(); j++) {
			n.ml.elementAt(j).accept(this);
		}
		tabela.endScope();
	}

	public void visit(ClassDeclExtends n) {
		Simbolo classe = Simbolo.symbol(n.i.s);
		tabela.addClass(classe);
		tabela.beginScope(classe);
		for (int i = 0; i < n.vl.size(); i++) {
			n.vl.elementAt(i).accept(this);
		}
		for (int j = 0; j < n.ml.size(); j++) {
			n.ml.elementAt(j).accept(this);
		}
		tabela.endScope();
	}

	public void visit(VarDecl n) {
		tabela.addVariable(Simbolo.symbol(n.i.s), n.t);
	}

	public void visit(MethodDecl n) {
		Type returnType = n.t;
		Simbolo name = Simbolo.symbol(n.i.s);
		ArrayList<String> arguments = new ArrayList<String>();
		for (int i = 0; i < n.fl.size(); i++) {
			arguments.add(n.fl.elementAt(i).t.toString());
			arguments.add(n.fl.elementAt(i).i.s);
		}
		tabela.addMethod(returnType, name, arguments);
		tabela.beginScope(name);
		for (int i = 0; i < n.vl.size(); i++) {
			n.vl.elementAt(i).accept(this);
		}
		tabela.endScope();
	}

	public void visit(Formal n) {
	}

	public void visit(IntArrayType n) {
	}

	public void visit(BooleanType n) {
	}

	public void visit(IntegerType n) {
	}

	public void visit(IdentifierType n) {
	}

	public void visit(Block n) {
	}

	public void visit(If n) {
	}

	public void visit(While n) {
	}

	public void visit(Print n) {
	}

	public void visit(Assign n) {
	}

	public void visit(ArrayAssign n) {
	}

	public void visit(And n) {
	}

	public void visit(LessThan n) {
	}

	public void visit(Plus n) {
	}

	public void visit(Minus n) {
	}

	public void visit(Times n) {
	}

	public void visit(ArrayLookup n) {
	}

	public void visit(ArrayLength n) {
	}

	public void visit(Call n) {
	}

	public void visit(IntegerLiteral n) {
	}

	public void visit(True n) {
	}

	public void visit(False n) {
	}

	public void visit(IdentifierExp n) {
	}

	public void visit(This n) {
	}

	public void visit(NewArray n) {
	}

	public void visit(NewObject n) {
	}

	public void visit(Not n) {
	}

	public void visit(Identifier n) {
	}

}
